package com.club.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.club.common.constant.Constant;
import com.club.common.security.MyPasswordEncoder;
import com.club.entity.*;
import com.club.mapper.SysUserMapper;
import com.club.service.SysRoleService;
import com.club.service.SysUserRoleService;
import com.club.service.SysUserService;
import com.club.util.DateUtil;
import com.club.util.RedisUtil;
import com.club.util.StringUtil;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.security.Principal;
import java.util.*;

/**
 * 用户Controller控制器
 *
 * @author chaochao(vx : zhangfec)
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/sys/user")
@Api(tags = "用户Controller")
public class SysUserController {

    private final SysUserService sysUserService;

    private final SysRoleService sysRoleService;

    private final SysUserRoleService sysUserRoleService;

    private final MyPasswordEncoder myPasswordEncoder;

    private final SysUserMapper sysUserMapper;

    private final RedisUtil redisUtil;

    @Value("${avatarImagesFilePath}")
    private String avatarImagesFilePath;

    @Value("${acaterAccessPath}")
    private String acaterAccessPath;

    @GetMapping("/info")
    @PreAuthorize("hasAuthority('system:user:query')")
    public R userInfo(Principal principal) {
        Map<String, Object> resultMap = new HashMap<>();
        SysUser currentUser = sysUserService.getByUserName(principal.getName());
        resultMap.put("currentUser", currentUser);
        return R.ok(resultMap);
    }

    /**
     * 验证用户名
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/checkUserName")
    @PreAuthorize("hasAuthority('system:user:query')")
    public R checkUserName(@RequestBody SysUser sysUser) {
        if (sysUserService.getByUserName(sysUser.getUsername()) == null) {
            return R.ok();
        } else {
            return R.error();
        }
    }

    @PostMapping("/list")
    @PreAuthorize("hasAuthority('system:user:query')")
    public R list(@RequestBody PageBean pageBean) {
        System.out.println("pageBean:" + pageBean);
        String query = pageBean.getQuery().trim();
        Page<SysUser> pageResult = sysUserService.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()), new QueryWrapper<SysUser>().like(StringUtil.isNotEmpty(query), "username", query));
        List<SysUser> userList = pageResult.getRecords();
        for (SysUser user : userList) {
            // 获取角色
            List<SysRole> roleList = sysRoleService.list(new QueryWrapper<SysRole>().inSql("id", "select role_id from sys_user_role where user_id=" + user.getId()));
            // 设置角色
            // user.setRoles(roleList.stream().map(SysRole::getName).collect(Collectors.joining(",")));
            user.setSysRoleList(roleList);
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userList", userList);
        resultMap.put("total", pageResult.getTotal());
        return R.ok(resultMap);
    }

    /**
     * 添加或者修改
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:user:add')" + "||" + "hasAuthority('system:user:edit')")
    public R save(@RequestBody @Valid SysUser sysUser) {
        if (sysUser.getId() == null || sysUser.getId() == -1) {
            sysUser.setCreateTime(new Date());
            sysUser.setPassword(myPasswordEncoder.encode(sysUser.getPassword()));
            sysUserService.save(sysUser);
        } else {
            sysUser.setUpdateTime(new Date());
            sysUserService.updateById(sysUser);
        }
        return R.ok();
    }

    /**
     * 修改密码
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/updateUserPwd")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public R updateUserPwd(@RequestBody SysUser sysUser) {
        SysUser currentUser = sysUserService.getById(sysUser.getId());
        currentUser.setPassword(myPasswordEncoder.encode(sysUser.getNewPassword()));
        sysUserService.updateById(currentUser);
        return R.ok();
    }

    /**
     * 更新status状态
     *
     * @param id
     * @param status
     * @return
     */
    @GetMapping("/updateStatus/{id}/status/{status}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public R updateStatus(@PathVariable(value = "id") Integer id, @PathVariable(value = "status") String status) {
        SysUser sysUser = sysUserService.getById(id);
        sysUser.setStatus(status);
        sysUserService.saveOrUpdate(sysUser);
        redisUtil.removeByPrex(Constant.AUTHORITY_KEY);
        return R.ok();
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('system:user:query')")
    public R findById(@PathVariable(value = "id") Integer id) {
        SysUser sysUser = sysUserService.getById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("sysUser", sysUser);
        return R.ok(map);
    }

    /**
     * 重置密码
     *
     * @param id
     * @return
     */
    @GetMapping("/resetPassword/{id}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public R resetPassword(@PathVariable(value = "id") Integer id) {
        SysUser sysUser = sysUserService.getById(id);
        sysUser.setPassword(myPasswordEncoder.encode(Constant.DEFAULT_PASSWORD));
        sysUser.setUpdateTime(new Date());
        sysUserService.updateById(sysUser);
        return R.ok();
    }


    /**
     * 修改用户头像
     *
     * @param sysUser
     * @return
     */
    @RequestMapping("/updateAvatar")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public R updateAvatar(@RequestBody SysUser sysUser) {
        SysUser currentUser = sysUserService.getById(sysUser.getId());
        currentUser.setAvatar(sysUser.getAvatar());
        sysUserService.updateById(currentUser);
        return R.ok();
    }

    /**
     * 上传用户头像图片
     *
     * @param file
     * @return
     * @throws Exception
     */
    @RequestMapping("/uploadImage")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Map<String, Object> uploadImage(MultipartFile file) throws Exception {
        Map<String, Object> resultMap = new HashMap<>();
        if (!file.isEmpty()) {
            // 获取文件名
            String originalFilename = file.getOriginalFilename();
            String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName = DateUtil.getCurrentDateStr() + suffixName;
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(avatarImagesFilePath + newFileName));
            resultMap.put("code", 0);
            resultMap.put("msg", "上传成功");
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("title", newFileName);
            dataMap.put("src", acaterAccessPath + newFileName);
            resultMap.put("data", dataMap);
        }
        return resultMap;
    }

    /**
     * 删除
     *
     * @param ids
     * @return
     */
    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('system:user:delete')")
    public R delete(@RequestBody Long[] ids) {
        sysUserService.removeByIds(Arrays.asList(ids));
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id", ids));
        redisUtil.removeByPrex(Constant.AUTHORITY_KEY);
        return R.ok();
    }

    /**
     * 用户角色授权
     *
     * @param userId  用户id
     * @param roleIds 角色ids
     * @return R
     */
    @Transactional
    @PostMapping("/grantRole/{userId}")
    @PreAuthorize("hasAuthority('system:user:role')")
    public R grantRole(@PathVariable("userId") Long userId, @RequestBody Long[] roleIds) {
        List<SysUserRole> userRoleList = new ArrayList<>();
        Arrays.stream(roleIds).forEach(r -> {
            SysUserRole sysUserRole = SysUserRole.builder()
                    .roleId(r)
                    .userId(userId)
                    .build();
            userRoleList.add(sysUserRole);
        });
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", userId));
        sysUserRoleService.saveBatch(userRoleList);
        redisUtil.removeByPrex(Constant.AUTHORITY_KEY);
        return R.ok();
    }


    /**
     * 统计用户性别
     *
     * @return R
     */
    @GetMapping("/getCountBySex")
    public R getCountBySex() {
        Map<String, Object> reponseMap = new HashMap<>();
        reponseMap.put("data", sysUserMapper.getCountBySex());
        return R.ok(reponseMap);
    }
}
